package com.pay.cloud.activity;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.pay.cloud.DataFactory;
import com.pay.cloud.DataStore;
import com.pay.cloud.IconFontFactory;
import com.pay.cloud.KeyInfo;
import com.pay.cloud.Loading;
import com.pay.cloud.PayMode;
import com.pay.cloud.R;
import com.pay.cloud.ScanListener;
import com.pay.cloud.StatusListener;
import com.pay.cloud.SubScreenFactory;
import com.pay.cloud.fragment.PayCancelFragment;
import com.pay.cloud.fragment.PayExpressionFragment;
import com.pay.cloud.fragment.PayIngAbstract;
import com.pay.cloud.fragment.PayIngFragment;
import com.pay.cloud.fragment.PayScanFragment;
import com.pay.cloud.fragment.TipFragment;
import com.pay.cloud.fragment.TipFragment.TipType;
import com.pay.cloud.fragment.TipHorizontalFragment;

import static com.pay.cloud.KeyInfo.KEY_CANCEL;
import static com.pay.cloud.KeyInfo.KEY_ENTER;
import static com.pay.cloud.fragment.TipFragment.TipType.ERROR;
import static com.pay.cloud.fragment.TipFragment.TipType.FAIL;
import static com.pay.cloud.fragment.TipFragment.TipType.SUCCESS;
import static com.pay.cloud.fragment.TipFragment.TipType.WAIT;


public class MainActivity extends AbstractActivity implements ScanListener, StatusListener, PayIngAbstract.PayFinishListener {
    private boolean fixedPayPause = true;
    private Handler fixedPayHandler = new Handler();
    private Runnable fixedPayRunnable = () -> {
        if (!fixedPayPause) {
            showPayScan();
        }
    };
    private PayMode mode;
    private String maxAmount;
    private String curAmount;
    private Fragment msgFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!allPermissionsGranted()) {
            ActivityCompat.requestPermissions(
                    this, new String[]{Manifest.permission.CAMERA}, 10);
        }

        DataStore store = DataFactory.getDataStore();

        String outMchId = store.getOutMchId();
        if (null != outMchId && !outMchId.isEmpty()) {

            LinearLayout layout = findViewById(R.id.bind_info);
            layout.setVisibility(LinearLayout.VISIBLE);

            Typeface tf = IconFontFactory.getHalflings(this);
            TextView icShopView = findViewById(R.id.icon_shop);
            TextView icUserView = findViewById(R.id.icon_user);
            icShopView.setTypeface(tf);
            icUserView.setTypeface(tf);

            TextView shopNameView = findViewById(R.id.shop_name);
            TextView staffNameView = findViewById(R.id.staff_name);
            shopNameView.setText(store.getShopName());
            staffNameView.setText(store.getStaffName());
        }

        mode = store.getMode();
        maxAmount = store.getMaxAmount();

        TextView modeView = findViewById(R.id.text_mode_name);
        modeView.setText(mode.getText());
        if (mode == PayMode.FIXED) {
            curAmount = store.getFixAmount();
            TextView amountView = findViewById(R.id.text_pay_amount);
            amountView.setText(curAmount);
            if (!fixedPayPause) {
                showPayScan();
            } else {
                modeView.setText(mode.getText() + "(暂停)");
            }
        } else {
            showPayExpression();
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        fixedPayHandler.removeCallbacks(fixedPayRunnable);
    }

    @Override
    public boolean onKeyDown(KeyInfo keyInfo) {
        if (mode == PayMode.FIXED) {
            if (keyInfo == KEY_ENTER || keyInfo == KEY_CANCEL) {
                TextView modeView = findViewById(R.id.text_mode_name);
                if (fixedPayPause) {
                    modeView.setText(mode.getText());
                    fixedPayPause = false;
                    showPayScan();
                } else {
                    modeView.setText(mode.getText() + "(暂停)");
                    fixedPayPause = true;
                    if (msgFragment instanceof PayScanFragment) {
                        showPayEmpty();
                    }
                }
            }
            return true;
        }

        if (msgFragment instanceof PayExpressionFragment) {
            curAmount = ((PayExpressionFragment) msgFragment).statAmount(keyInfo);
            TextView amountView = this.findViewById(R.id.text_pay_amount);
            amountView.setText(curAmount);
            if (keyInfo == KEY_ENTER && Float.parseFloat(curAmount) > 0.00) {
                if (Float.parseFloat(curAmount) <= Float.parseFloat(maxAmount)) {
                    showPayScan();
                } else {
                    showToast("金额上限为：" + maxAmount + "元");
                }
            }
        } else if (msgFragment instanceof PayScanFragment) {
            if (keyInfo == KEY_CANCEL) {
                showPayExpression();
            }
        } else if (msgFragment instanceof PayIngFragment) {
            PayIngFragment fragment = (PayIngFragment) msgFragment;
            TipType type = fragment.getType();

            if (keyInfo == KEY_CANCEL && type == WAIT) {
                //showPayCancel(fragment.getOrderNo(), fragment.getAmount());
                showPayExpression();
            } else if (keyInfo == KEY_CANCEL && (type == FAIL || type == ERROR)) {
                showPayExpression();
            } else if (keyInfo == KEY_ENTER && (type == FAIL || type == ERROR)) {
                showPayScan();
            } else if (keyInfo == KEY_ENTER && type != WAIT) {
                showPayExpression();
            } else if (type == SUCCESS) {
                showPayExpression();
                curAmount = ((PayExpressionFragment) msgFragment).statAmount(keyInfo);
                TextView amountView = this.findViewById(R.id.text_pay_amount);
                amountView.setText(curAmount);
            }
        } else if (msgFragment instanceof PayCancelFragment) {
            PayCancelFragment fragment = (PayCancelFragment) msgFragment;
            TipType type = fragment.getType();
            if (keyInfo == KEY_ENTER && type == SUCCESS) {
                showPayExpression();
            } else if (keyInfo == KEY_ENTER && type == FAIL) {
                showPayCancel(fragment.getOrderNo(), fragment.getAmount());
            } else if (keyInfo == KEY_CANCEL && type != WAIT) {
                showPayExpression();
            }
        } else if (msgFragment instanceof TipFragment && ((TipFragment)msgFragment).getType() == ERROR) {
            if (keyInfo == KEY_ENTER || keyInfo == KEY_CANCEL) {
                showPayExpression();
            }
        }

        return false;
    }

    @Override
    public boolean onScan(String barcode) {
        showPaying(barcode);
        return true;
    }

    @Override
    public void onFinish() {
        startSubScreenAutoToWelcome();
        autoFixedPay();
    }

    @Override
    public void onError(String msg) {
        setMsgFragment(new TipHorizontalFragment(ERROR, msg));
    }

    @Override
    public void onSuccess(String msg) {
        setMsgFragment(new TipHorizontalFragment(SUCCESS, msg));
    }

    private void autoFixedPay() {
        if (mode == PayMode.FIXED) {
            fixedPayHandler.removeCallbacks(fixedPayRunnable);
            if (!fixedPayPause) {
                fixedPayHandler.postDelayed(fixedPayRunnable, 3000);
            }
        }
    }

    private void setMsgFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.disallowAddToBackStack();
        if (null == fragment) {
            fragmentTransaction.remove(msgFragment);
            msgFragment = null;
        } else {
            msgFragment = fragment;
            fragmentTransaction.replace(R.id.pay_info_container, msgFragment);
        }
        fragmentTransaction.commit();
    }

    private void startSubScreenAutoToWelcome() {
        SubScreenFactory.startSubScreen(() -> {
            try {
                Thread.sleep(3000);
                if (mode != PayMode.FIXED) {
                    SubScreenFactory.flushSubScreenToWelcome(this);
                }
            } catch (InterruptedException ignored) {

            }
        }, true);
    }

    private void showPayEmpty() {
        setMsgFragment(null);
        SubScreenFactory.flushSubScreenToWelcome(this);
    }

    private void showPayExpression() {
        curAmount = "0.00";
        setMsgFragment(new PayExpressionFragment());
        TextView amountView = this.findViewById(R.id.text_pay_amount);
        amountView.setText(curAmount);
    }

    private void showPayScan() {
        PayScanFragment fragment = new PayScanFragment(curAmount);
        fragment.setListener(this);
        setMsgFragment(fragment);
    }

    private void showPaying(String barcode) {
        setMsgFragment(new PayIngFragment(this, barcode, curAmount));
    }

    private void showPayCancel(String orderNo, String amount) {
        setMsgFragment(new PayCancelFragment(orderNo, amount));
    }

    private boolean allPermissionsGranted() {
        return ContextCompat.checkSelfPermission(
                this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    }

}
